package com.example.work1.client;

import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 *  客户端
 */
public class Client {
    /*
        java.net.Socket 套接字
        Socket封装了TCP协议的通讯细节，使用它可以和远端计算机建立网络链接，并基于
        两条流(一条输入，一条输出)的读写与对方进行数据交换。
     */
    private Socket socket;
    private boolean isLogin;

    public static void main(String[] args) {
        //实际开发中不会在main方法中写业务逻辑，main方法是静态方法会有很多不便
        Client client = new Client();//调用构造器初始化客户端
        client.start();//调用start方法使客户端开始工作
    }

    /**
     * 构造器，用于初始化客户端
     */
    public Client(){
        try {
            System.out.println("正在链接服务端...");
            /*
                Socket实例化时就是与服务端建立链接的过程，此时需要传入两个
                参数
                参数1:服务端的IP地址，用于找到服务端的计算机
                参数2:服务端口，用于找到服务端程序

                如何查看IP地址:
                windows:窗口键+R 打开控制台
                        输入ipconfig
                        查看以太网适配器-以太网，找到ipv4查看自己的IP地址

                mac:打开[终端]程序
                    输入/sbin/ifconfig查看自己的IP地址
             */
//            socket = new Socket("127.0.0.1",8088);//127.0.0.1和localhost都是表示本机
            socket = new Socket("localhost",8080);
            System.out.println("与服务端成功链接!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 用于客户端开始工作的方法
     */
    public void start(){
        /*
            Socket提供的方法:
            OutputStream getOutputStream()
            通过Socket获取一个字节输出流，通过向该流写出字节，就可以发送给远端链接
            的计算机的Socket了
         */
        try {
//            OutputStream out = socket.getOutputStream();
//            OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
//            BufferedWriter bw = new BufferedWriter(osw);
//            PrintWriter pw = new PrintWriter(bw, true);

            login();

            //将接收服务端发送过来消息的线程启动
            ServerHandler handler = new ServerHandler();
            Thread t = new Thread(handler);
            t.setDaemon(true);
            t.start();

            //聊天室
//            System.out.println("开始聊天吧");
//            Scanner scanner = new Scanner(System.in);
//
//            while(true) {
//                String line = scanner.nextLine();
//                if("exit".equalsIgnoreCase(line)){
//                    break;
//                }
//                pw.println(line);
//            }
            while (true) {//维持程序长时间运行
                // 执行任务
                try {
                    Thread.sleep(1000); // 每秒执行一次
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt(); // 处理异常
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                //socket的close方法会进行四次挥手
                //并且也会关闭通过socket获取的输入流和输出流
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void login() throws IOException {
        Scanner scanner = new Scanner(System.in);

        OutputStream out = socket.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
        BufferedWriter bw = new BufferedWriter(osw);
        PrintWriter pw = new PrintWriter(bw, true);
        // 用户登录
        String username = "";
        String password = "";
        while (true) {

            System.out.println("请输入用户名:");
            username = scanner.nextLine();
            System.out.println("请输入密码:");
            password = scanner.nextLine();

            // 这里可以加入对用户名和密码的验证逻辑
            if (validateCredentials(username, password)) {
                String order = "login,"+username+","+password;
                pw.println(order); // 发送给服务端
                System.out.println("等待登录验证...");
                break;
            } else {
                System.out.println("用户名或密码为空。");
            }
        }
    }

    private void menu() throws IOException {
        Scanner scanner=new Scanner(System.in);

        boolean inStudentManagement = true;

        while (inStudentManagement) {
            System.out.println("-- 学生信息管理 --");
            System.out.println("1. 新增学生");
            System.out.println("2. 修改学生");
            System.out.println("3. 删除学生");
            System.out.println("4. 查询学生");
            System.out.println("5. 信息统计");
            System.out.println("0. 退出");

            int choice;

            // 循环直到用户输入一个整数
            while (true) {
                System.out.print("请选择操作（输入对应编号）：");

                // 检查用户输入是否为整数
                if (scanner.hasNextInt()) {
                    choice = scanner.nextInt();
                    break; // 输入有效，跳出循环
                } else {
                    System.out.println("输入无效，请重新输入一个整数。");
                    scanner.next(); // 清除缓冲区中的无效输入
                }
            }
            switch (choice) {
                case 1 -> studentAdd();
                case 2 -> studentModify();
                case 3 -> studentDelete();
                case 4 -> {
                    studentQuery();
                    // 等待服务器响应后再显示菜单
                    System.out.println("按任意键继续...");
                    scanner.next(); // 等待用户输入
                }
                case 5 -> messageStatistics();
                case 0 -> {
                    System.exit(0);
//                    inStudentManagement = false;
                }
                default -> System.out.println("无效的选择，请重新输入");
            }
        }
    }

    private void messageStatistics() throws IOException {
        Scanner scanner=new Scanner(System.in);

        boolean inMessageStatistics = true;

        while (inMessageStatistics) {
            System.out.println("-- 信息统计 --");
            System.out.println("1 - 统计输出总分最高和最低的学生");
            System.out.println("2 - 归集显示同一个入学时间的学生");
            System.out.println("0 - 返回");

            int choice;

            // 循环直到用户输入一个整数
            while (true) {
                System.out.print("请选择操作（输入对应编号）：");

                // 检查用户输入是否为整数
                if (scanner.hasNextInt()) {
                    choice = scanner.nextInt();
                    break; // 输入有效，跳出循环
                } else {
                    System.out.println("输入无效，请重新输入一个整数。");
                    scanner.next(); // 清除缓冲区中的无效输入
                }
            }
            switch (choice) {
                case 1 -> {
                    studentSort();
                    // 等待服务器响应后再显示菜单
                    System.out.println("按任意键继续...");
                    scanner.next(); // 等待用户输入
                }
                case 2 -> {
                    studentGroup();
                    // 等待服务器响应后再显示菜单
                    System.out.println("按任意键继续...");
                    scanner.next(); // 等待用户输入
                }
                case 0 -> inMessageStatistics = false;
                default -> System.out.println("无效的选择，请重新输入");
            }
        }
    }

    private void studentGroup() throws IOException {
        // 发送查询请求给服务器
        String order = "group" ;

        OutputStream out = socket.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
        BufferedWriter bw = new BufferedWriter(osw);
        PrintWriter pw = new PrintWriter(bw, true);
        pw.println(order); // 发送给服务端
        // 启动一个新线程来接收服务器的响应
        new Thread(() -> {
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
                String response;
                boolean isList = false;
                while ((response = br.readLine()) != null) {
                    if(response.startsWith("归集")){
                        System.out.println(response);
                        isList = true;
                    }else if (isList) {
                        if (response.isEmpty()) {
                            break;
                        } else {
                            System.out.println(response); // 打印专业信息
                        }
                    }

                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }

    private void studentSort() throws IOException {
        // 发送查询请求给服务器
        String order = "sort" ;

        OutputStream out = socket.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
        BufferedWriter bw = new BufferedWriter(osw);
        PrintWriter pw = new PrintWriter(bw, true);
        pw.println(order); // 发送给服务端

        // 启动一个新线程来接收服务器的响应
        new Thread(() -> {
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
                String response;
                boolean isList = false;
                while ((response = br.readLine()) != null) {
                    if(response.startsWith("总分")) {
                        System.out.println(response);
                        isList = true;
                    }else if(isList){
                        if (response.isEmpty()) {
                            break; // 遇到空行，结束列表
                        } else {
                            System.out.println(response); // 打印专业信息
                        }
                    }

                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }

    private void studentQuery() throws IOException {
        Scanner scanner = new Scanner(System.in);

        System.out.print("请输入要查询的学生ID: ");
        String id = scanner.nextLine().trim();

        // 发送查询请求给服务器
        String queryOrder = "query," + id;

        OutputStream out = socket.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
        BufferedWriter bw = new BufferedWriter(osw);
        PrintWriter pw = new PrintWriter(bw, true);
        pw.println(queryOrder); // 发送给服务端

        // 启动一个新线程来接收服务器的响应
        new Thread(() -> {
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
                String response;
                while ((response = br.readLine()) != null) {
                    if(response.startsWith("查询"))
                        System.out.println(response);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }

    private void studentModify() throws IOException {
        Scanner scanner = new Scanner(System.in);
        String id;
        while (true){
            System.out.print("请输入要修改的学生ID: ");
            id = scanner.nextLine().trim();
            if(id.isEmpty()){
                System.out.println("学生ID为空！");
            }else{
                break;
            }
        }


        String gender;
        while (true) {
            System.out.print("请输入新的性别 (男/女) 或按 Enter 保持不变: ");
            gender = scanner.nextLine().trim();
            if (gender.isEmpty() || gender.equals("男") || gender.equals("女")) {
                break;
            }
            System.out.println("性别输入不合法！请重新输入 (男/女)。");
        }

        String enrollmentDate;
        while (true) {
            System.out.print("请输入新的入学时间 (YYYY-MM-DD) 或按 Enter 保持不变: ");
            enrollmentDate = scanner.nextLine().trim();
            if (enrollmentDate.isEmpty() || enrollmentDate.matches("\\d{4}-\\d{2}-\\d{2}")) {
                break;
            }
            System.out.println("日期格式不正确！请使用 YYYY-MM-DD 格式。");
        }

        OutputStream out = socket.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
        BufferedWriter bw = new BufferedWriter(osw);
        PrintWriter pw = new PrintWriter(bw, true);

        Set<String> majorIds = new HashSet<>(); // 存储专业编号
        String majorId = "-1";
        while (true) {
            String listOrder = "majorlist";
            pw.println(listOrder);
            // 启动一个新线程来接收服务器的响应
            new Thread(() -> {
                try {
                    BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
                    String response;
                    boolean isProfessionalList = false;

                    while ((response = br.readLine()) != null) {
                        if (response.startsWith("专业列表")) {//特判第一行，以后行放行
                            System.out.println(response); // 打印标题
                            isProfessionalList = true; // 开始专业列表
                        } else if (isProfessionalList) {
                            if (response.isEmpty()) {
                                break;
                            } else {
                                System.out.println(response); // 打印专业信息
                                // 提取专业编号
                                String majorIdFromResponse = response.split(",")[0].split(":")[1].trim();
                                majorIds.add(majorIdFromResponse); // 添加编号到集合
                            }
                        }
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();
            System.out.println("请输入新的专业编号 或按 Enter 保持不变: ");
            majorId = scanner.nextLine().trim();
            // 判断用户输入的专业编号是否存在于集合中
            if (!majorId.equals("-1")) {
                if (majorIds.contains(majorId)) {
                    System.out.println("您选择的专业编号 " + majorId + " 存在。");
                    break; // 选择有效，退出循环
                } else {
                    System.out.println("输入的专业编号 " + majorId + " 不存在，请重新输入。");
                }
            } else {
                System.out.println("输入格式不正确，请输入一个有效的数字");
            }
        }

        double score;
        while (true) {
            System.out.print("请输入新的成绩 或按 Enter 保持不变: ");
            String scoreInput = scanner.nextLine().trim();
            if (scoreInput.isEmpty()) {
                score = -1; // 表示不修改
                break;
            }
            try {
                score = Double.parseDouble(scoreInput);
                if (score >= 0) {
                    break;
                } else {
                    System.out.println("成绩不能为负数！");
                }
            } catch (NumberFormatException e) {
                System.out.println("成绩输入不合法！");
            }
        }

        if(!(gender.isEmpty()&&majorId.isEmpty()&&enrollmentDate.isEmpty()&&score==-1)){
            // 发送修改指令给服务器
            String order = "modify," + id+","+gender+","+enrollmentDate+","+majorId+","+score;
            pw.println(order); // 发送给服务端
        }else{
            System.out.println("未进行修改");
        }

    }

    private void studentDelete() throws IOException {
        Scanner scanner = new Scanner(System.in);

        String id;
        while (true) {
            System.out.print("请输入学生ID: ");
            id = scanner.nextLine().trim();
            if (!id.isEmpty()) {
                String order="delete,"+id;

                OutputStream out = socket.getOutputStream();
                OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
                BufferedWriter bw = new BufferedWriter(osw);
                PrintWriter pw = new PrintWriter(bw, true);
                pw.println(order); // 发送给服务端
                break;
            }
            System.out.println("学生ID不能为空！");
        }
    }

    private void studentAdd() throws IOException {
        Scanner scanner = new Scanner(System.in);

        String name;
        while (true) {
            System.out.print("请输入姓名: ");
            name = scanner.nextLine().trim();
            if (!name.isEmpty()) {
                break;
            }
            System.out.println("姓名不能为空！");
        }

        String gender;
        while (true) {
            System.out.print("请输入性别 (男/女): ");
            gender = scanner.nextLine().trim();
            if (gender.equals("男") || gender.equals("女")) {
                break;
            }
            System.out.println("性别输入不合法！请重新输入 (男/女)。");
        }

        String enrollmentDate;
        while (true) {
            System.out.print("请输入入学时间 (YYYY-MM-DD): ");
            enrollmentDate = scanner.nextLine().trim();
            if (enrollmentDate.matches("\\d{4}-\\d{2}-\\d{2}")) {
                break;
            }
            System.out.println("日期格式不正确！请使用 YYYY-MM-DD 格式。");
        }

        double score;
        while (true) {
            System.out.print("请输入成绩: ");
            if (scanner.hasNextDouble()) {
                score = scanner.nextDouble();
                if (score >= 0) {
                    break;
                }
                System.out.println("成绩不能为负数！");
            } else {
                System.out.println("成绩输入不合法！");
                scanner.next(); // 清除无效输入
            }
        }

        String order="add,"+name+","+gender+","+enrollmentDate+","+score;

        OutputStream out = socket.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
        BufferedWriter bw = new BufferedWriter(osw);
        PrintWriter pw = new PrintWriter(bw, true);
        pw.println(order); // 发送给服务端
    }


    private boolean validateCredentials(String username, String password) {
        // 检查用户名和密码是否非空
        return username != null && !username.trim().isEmpty() && password != null && !password.trim().isEmpty(); // 为空返回false
    }


    private class ServerHandler implements Runnable{
        @Override
        public void run() {
            try {
                //通过socket获取输入流,用于读取服务端发送过来的消息
                InputStream in = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(in, StandardCharsets.UTF_8);
                BufferedReader br = new BufferedReader(isr);
                String line;
                while((line = br.readLine())!=null){
                    System.out.println(line);
                    if(line.equals("登录失败")){
                        isLogin=false;
                        login();
                    }
                    if(line.equals("登录成功")){
                        isLogin=true;
                        menu();
                    }
                }

            } catch (IOException e) {

            }
        }
    }


}





